package com.ruoyi.common.utils;


import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;

/**
 * @author WuXiaoQiang
 */
public class MoneyTools {

    /**
     * 金额反格式化 如：2,221,345.447 转换为 2221345.447
     */
    public static double reverseFormat(String money) {
        double result = 0;
        try {
            result = new DecimalFormat().parse(money).doubleValue();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }

    /*数值格式化*/
    public static String numFormat(double num, int maxPrecision, int minPrecision, boolean format) {
        return numFormat(num, maxPrecision, minPrecision, format, 1);
    }

    /*金额格式化*/
    public static String moneyFormat(double num, int maxPrecision, int minPrecision, boolean format) {
        return numFormat(num, maxPrecision, minPrecision, format, 2);
    }

    /*百分比*/
    public static String percentFormat(double num, int maxPrecision, int minPrecision, boolean format) {
        return numFormat(num, maxPrecision, minPrecision, format, 3);
    }

    /**
     * 数字格式化
     * 小数四舍五入
     */
    private static String numFormat(double num, int maxPrecision, int minPrecision, boolean format, int flag) {
        String result = "";
        try {
            NumberFormat nf = null;
            if (flag == 1) {
                nf = NumberFormat.getInstance(); //数字  getNumberInstance();
            } else if (flag == 2) {
                nf = NumberFormat.getCurrencyInstance(); //货币  Locale.US
            } else if (flag == 3) {
                nf = NumberFormat.getPercentInstance(); //百分数
            }

            if (maxPrecision < minPrecision && maxPrecision > 0) {
                throw new Exception("Maximum Precision cannot be less than minimum Precision");
            }
            if (maxPrecision > 0) {
                nf.setMaximumFractionDigits(maxPrecision); //允许小数最大的数位
            }
            if (minPrecision > 0) {
                nf.setMinimumFractionDigits(minPrecision); //允许小数最小位数
            }
            nf.setGroupingUsed(format); //格式：false 999999  true 9,999,999
            //  nf.setMaximumIntegerDigits( 10 );//设置整数最大位数。
            //  nf.setMinimumIntegerDigits(0);//设置整数最小位数.
            result = nf.format(num);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }

    /**
     * 数字格式化
     * @param value : 数字
     * @param precision：保留几位小数,不保留为0
     * @param format：是否格式化  9,999,999
     * @return
     */
    public static String numberFormat(String value, int precision, boolean format) {
        try {
            StringBuffer sb = new StringBuffer();
            if (precision < 0) {
                throw new Exception("Precision cannot be less than 0");
            }

            //数值验证
            if (StringUtils.isBlank(value) || !value.matches("^[-+]?(\\d+\\.{0,1}\\d*)$")) {
                sb.append("0");
                if (precision > 0) {
                    sb.append(".");
                    for (int i = 0; i < precision; i++) {
                        sb.append("0");
                    }
                }
                return sb.toString();
            }

            //是否格式化
            if (format) {
                sb.append(",###");
            } else {
                sb.append("#");
            }
            //保留小数
            if (precision > 0) {
                sb.append(".");
                for (int i = 0; i < precision; i++) {
                    sb.append("0");
                }
            }
            BigDecimal bd = new BigDecimal(value);
            DecimalFormat df = new DecimalFormat(sb.toString());
            return df.format(bd.setScale(precision, BigDecimal.ROUND_DOWN));
        } catch (Exception e) {
            e.printStackTrace();
        }
        // ,###.000  每三位用逗号分隔，保留三位小数
        // #  取所有整数
        // #.##%  以百分比方式计数，并取两位小数
        return null;
    }

    // 分转元
    public static String fenToYuan(String amount) {
        NumberFormat format = NumberFormat.getInstance();
        try {
            Number number = format.parse(amount);
            double temp = number.doubleValue() / 100.00;
            format.setGroupingUsed(false);
            // 设置返回的小数部分所允许的最大位数
            format.setMaximumFractionDigits(2);
            amount = format.format(temp);
            if (amount.indexOf(".") == -1) {
                amount += ".00";
            } else {
                if (amount.length() - amount.indexOf(".") == 2) {
                    amount += "0";
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return amount;
    }

    //创造BigDecimal对象        negate(); 相反数
    public static BigDecimal getAsBigDecimal(Object obj) {
        if (obj == null) {
            return new BigDecimal("0");
        }
        return new BigDecimal(obj.toString());
    }

    /**
     * 精确加法
     */
    public static double add(double value1, double value2) {
        return getAsBigDecimal(value1).add(getAsBigDecimal(value2)).doubleValue();
    }

    /**
     * 精确减法
     */
    public static double sub(double value1, double value2) {
        return getAsBigDecimal(value1).subtract(getAsBigDecimal(value2)).doubleValue();
    }

    /**
     * 精确乘法
     */
    public static double mul(double value1, double value2) {
        return getAsBigDecimal(value1).multiply(getAsBigDecimal(value2)).doubleValue();
    }

    /**
     * 精确除法 使用默认精度
     */
    public static double div(double value1, double value2) {
        return div(value1, value2, 10);
    }

    /**
     * 精确除法
     * @param scale 精度
     */
    public static double div(double value1, double value2, int scale) {
        if (scale < 0) {
            try {
                throw new IllegalAccessException("精确度不能小于0");
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        BigDecimal b1 = getAsBigDecimal(value1);
        BigDecimal b2 = getAsBigDecimal(value2);
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 精确取余
     */
    public static double remainder(double value1, double value2) {
        return getAsBigDecimal(value1).remainder(getAsBigDecimal(value2)).doubleValue();
    }

    /**
     * 比较大小： 小于-1  等于0  大于1
     */
    private static int compareTo(double value1, double value2) {
        return getAsBigDecimal(value1).compareTo(getAsBigDecimal(value2));
    }

    //value1是否大于value2
    public static boolean big(double value1, double value2) {
        return compareTo(value1, value2) == 1;
    }

    /**
     * value1是否等于value2
     */
    public static boolean equal(double value1, double value2) {
        return compareTo(value1, value2) == 0;
    }

    /**
     * value1是否小于value2
     */
    public static boolean little(double value1, double value2) {
        return compareTo(value1, value2) == -1;
    }
}
